package com.czn.shopdemo.utils;

/**
 * @author Zenan Chen
 * @date 2023/4/3 11:21
 */

import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.util.List;

public class FileUtil {
    private static Logger logger = LoggerFactory.getLogger(FileUtil.class);

    private FileUtil() {
    }

    /**
     * 创建目录
     *
     * @author LUOHENG2
     * @date 2018年1月9日 下午1:57:29
     */
    public static boolean createDir(String destDirName) {
        File dir = new File(destDirName);
        if (dir.exists()) {
            return true;
        }
        if (!destDirName.endsWith(File.separator)) {
            destDirName = destDirName + File.separator;
        }
        // 创建目录
        if (dir.mkdirs()) {
            logger.info("创建目录" + destDirName + "成功！");
            return true;
        } else {
            logger.info("创建目录" + destDirName + "失败！");
            return false;
        }
    }

    /**
     * 判断文件夹或文件是否存在
     *
     * @author luoheng2
     * @date 2018年11月30日 上午9:54:27
     */
    public static boolean isDir(String destDirName) {
        File dir = new File(destDirName);
        if (dir.exists()) {
            return true;
        }

        return false;
    }

    /**
     * 创建文件
     *
     * @author LUOHENG2
     * @date 2018年1月9日 下午1:59:18
     */
    public static boolean createFile(String destFileName) {
        File file = new File(destFileName);
        if (file.exists()) {
            logger.info("创建单个文件" + destFileName + "失败，目标文件已存在！");
            return false;
        }
        if (destFileName.endsWith(File.separator)) {
            logger.info("创建单个文件" + destFileName + "失败，目标文件不能为目录！");
            return false;
        }
        // 判断目标文件所在的目录是否存在
        if (!file.getParentFile().exists()) {
            // 如果目标文件所在的目录不存在，则创建父目录
            logger.info("目标文件所在目录不存在，准备创建它！");
            if (!file.getParentFile().mkdirs()) {
                logger.info("创建目标文件所在目录失败！");
                return false;
            }
        }
        // 创建目标文件
        try {
            if (file.createNewFile()) {
                logger.info("创建单个文件" + destFileName + "成功！");
                return true;
            } else {
                logger.info("创建单个文件" + destFileName + "失败！");
                return false;
            }
        } catch (IOException e) {
            logger.info("创建单个文件" + destFileName + "失败！" + e.getMessage());
            logger.error(e.getMessage());
            return false;
        }
    }

    public static boolean getDirEmpty(String path) {
        File file = new File(path);
        File[] listFiles = file.listFiles();
        if (listFiles != null && listFiles.length > 0) {
            //文件夹下有文件
            return false;
        }
        return true;
    }

    public static void WriteStringToFile(String filePath, String context) {
        PrintStream ps = null;
        try {
            File file = new File(filePath);
            if (!file.getParentFile().exists()) {
                createDir(file.getPath());
            }
            if (file.exists()) {
                if (file.delete()) {
                    logger.debug("删除文件成功");
                } else {
                    logger.info("删除文件失败");
                }
            }
            ps = new PrintStream(new FileOutputStream(file));
            ps.println(context);// 往文件里写入字符串
            ps.flush();
        } catch (FileNotFoundException e) {
            logger.error(e.getMessage());
        } finally {
            try {
                if (ps != null) {
                    ps.close();
                }
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        }
    }


    /**
     * 创建文件
     *
     * @param file
     * @param path
     * @param newFileName
     * @throws Exception
     */
    /**
     * 创建文件
     *
     * @param file
     * @param path
     * @param newFileName
     * @throws Exception
     */
    public static void createFile(MultipartFile file, String path, String newFileName) {
        InputStream is = null;
        FileOutputStream fos = null;
        FileInputStream fis = null;
        try {
            is = file.getInputStream();
            File sfile = stream2file(is);
            fis = new FileInputStream(sfile);
            // 如果文件夹不存在则创建
            File dirFile = new File(path);
            if (!dirFile.exists() && !dirFile.isDirectory()) {
                dirFile.mkdirs();
            }
            File saveFile = new File(path + "/" + newFileName);
            fos = new FileOutputStream(saveFile);
            int len = 0;
            byte[] buf = new byte[4096];
            while ((len = fis.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }
            fos.flush();
        } catch (Exception e) {
            logger.error("保存文件异常时，删除上传文件失败！");
        } finally {
            try {
                if (fos != null) fos.close();
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
            try {
                if (fis != null) fis.close();
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
            try {
                if (is != null) is.close();
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        }
    }

    /**
     * 文件流转文件
     *
     * @param in
     * @return
     * @throws IOException
     */
    public static File stream2file(InputStream in) throws IOException {
        String PREFIX = "stream2file";
        String SUFFIX = ".tmp";
        final File tempFile = File.createTempFile(PREFIX, SUFFIX);
        tempFile.deleteOnExit();
        try (FileOutputStream out = new FileOutputStream(tempFile)) {
            IOUtils.copy(in, out);
        }
        return tempFile;
    }

    /**
     * 删除文件
     *
     * @param fileName
     * @throws Exception
     */
    public static void deleteFile(String fileName) throws IOException {
        try {
            File file = new File(fileName);
            if (file.isDirectory()) { // 如果它是一个目录
                File[] files = file.listFiles(); // 声明目录下所有的文件
                for (int i = 0; i < files.length; i++) {
                    boolean isDelete = files[i].delete();
                    if (!isDelete) logger.info(files[i].getName() + "没有被删除！");
                }
            } else {
                logger.info("所删除的文件不存在");
            }
            boolean isDelete = file.delete(); // 删除文件或文件夹
            if (!isDelete) logger.info(file.getName() + "没有被删除！");
        } catch (Exception e) {
            logger.error(e.getMessage());
            throw new IOException("文件移除异常，请核实！");
        }
    }

    /**
     * 递归读取目录下得所有文件
     *
     * @param fileDir
     */
    public static void readFile(String fileDir, List<File> fileList) {
        File file = new File(fileDir);
        File[] files = file.listFiles();// 获取目录下的所有文件或文件夹
        if (files == null) {// 如果目录为空，直接退出
            return;
        }
        // 遍历，目录下的所有文件
        for (File f : files) {
            //logger.info(f.getPath());
            if (f.isFile()) {
                fileList.add(f);
            } else if (f.isDirectory()) {
                readFile(f.getAbsolutePath(), fileList);
            }
        }
    }

    /**
     * 递归删除目录下得所有文件
     *
     * @param file
     */
    public static void delDir(File file) {
        logger.info(file.getPath() + " 删除文件开始。。。。");
        if (file.isDirectory()) {
            File zFiles[] = file.listFiles();
            for (File file2 : zFiles) {
                delDir(file2);
            }
            if (file.delete()) {
                logger.info(file.getPath() + " 删除文件成功");
            } else {
                logger.debug(file.getPath() + "删除文件失败");
            }
        } else {
            if (file.delete()) {
                logger.debug(file.getPath() + "删除文件成功");
            } else {
                logger.debug(file.getPath() + "删除文件失败");
            }
        }
        logger.info(file.getPath() + " 删除文件结束。。。。");
    }

    /**
     * @param size 自动转换KB、MB、GB
     * @author LUOHENG2
     * @date 2019年5月7日 下午2:17:53
     */
    public static String getSize(long size) {
        // 如果字节数少于1024，则直接以B为单位，否则先除于1024，后3位因太少无意义
        double value = (double) size;
        if (value < 1024) {
            return String.valueOf(value) + "B";
        } else {
            double value1 = value / 1024;
            value = BigDecimal.valueOf(value1).setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
        }
        // 如果原字节数除于1024之后，少于1024，则可以直接以KB作为单位
        // 因为还没有到达要使用另一个单位的时候
        // 接下去以此类推
        if (value < 1024) {
            return String.valueOf(value) + "KB";
        } else {
            double value1 = value / 1024;
            value = BigDecimal.valueOf(value1).setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
        }
        if (value < 1024) {
            return String.valueOf(value) + "MB";
        } else {
            // 否则如果要以GB为单位的，先除于1024再作同样的处理
            double value1 = value / 1024;
            value = BigDecimal.valueOf(value1).setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
            return String.valueOf(value) + "GB";
        }
    }

    //下载本地文件
    public static void downloadFile(HttpServletResponse response, String fileName, String path) throws IOException {
//        BufferedInputStream br = null;
        OutputStream out = null;
//        FileInputStream fis = null;
        File file = new File(path);
        try (FileInputStream fis = new FileInputStream(file); BufferedInputStream br = new BufferedInputStream(fis)) {

            byte[] buf = new byte[4096];
            int len = 0;

            response.setHeader("Content-Disposition", "attachment; filename=\"" + new String(fileName.getBytes("utf-8"), "iso8859-1") + "\"");
            response.setContentType("application/octet-stream;charset=utf-8");
            out = response.getOutputStream();
            while ((len = br.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            out.flush();
        } catch (Exception e) {
            throw new RuntimeException("发生错误");
        } finally {
            response.flushBuffer();
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
    }


    //下载文件 根据流（例如HDFS）
    public static void downloadFile(HttpServletResponse response, String fileName, InputStream is) throws IOException {
        BufferedInputStream br = null;
        OutputStream out = null;
        try {
            br = new BufferedInputStream(is);
            byte[] buf = new byte[4096];
            int len = 0;

            response.setHeader("Content-Disposition", "attachment; filename=\"" + new String(fileName.getBytes("utf-8"), "iso8859-1") + "\"");
            response.setContentType("application/octet-stream;charset=utf-8");
            out = response.getOutputStream();
            while ((len = br.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            out.flush();
        } catch (Exception e) {
            throw new RuntimeException("发生错误");
        } finally {
            response.flushBuffer();
            try {
                if (out != null) {
                    out.close();
                }
                if (br != null) {
                    br.close();
                }
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
    }


}
